﻿using Sustainalytics.SharedEntities.RiskRatingsResearch;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.Tests
{
    [Trait("Category", "RiskRating")]
    public class SyncRiskRatingsDataIntegrationTests : BaseSyncRiskRatingTests
    {
        private readonly RiskRatingsSync riskRatingsSync;
        private readonly CoreRiskRatingsSync _coreRiskRatingsSync;

        public SyncRiskRatingsDataIntegrationTests(ITestOutputHelper output) : base(output)
        {
            AutoMapperConfig.RegisterMappings();
            riskRatingsSync = SimpleInjectorContainer.GetInstance<RiskRatingsSync>();
            _coreRiskRatingsSync = SimpleInjectorContainer.GetInstance<CoreRiskRatingsSync>();
        }

        [Fact]
        public async Task SyncCoreAndComprehensiveRiskRatings()
        {
            await _coreRiskRatingsSync.StartAsync();
            await riskRatingsSync.StartAsync(false);
        }

        [Fact]
        public async Task SyncComprehensiveRiskRatings()
        {
            await riskRatingsSync.StartAsync(false);
        }

        [Fact]
        public async Task SyncCoreRiskRatings()
        {
            await _coreRiskRatingsSync.StartAsync();
        }

        [Fact]
        public void OrderRiskRatingsResearchProfiles()
        {
            var profiles = new List<ComprehensiveRiskRatingResearchProfile>();

            var inputList = new List<MaterialEsgIssue>()
                {
                    new MaterialEsgIssue() { ExternalId = 1, SortKey = Timestamped(0), Type = Timestamped(MaterialIssueType.MaterialIssue), FinalWeight = Timestamped(0.1) },
                    new MaterialEsgIssue() { ExternalId = 2, SortKey = Timestamped(1), Type = Timestamped(MaterialIssueType.MaterialIssue), FinalWeight = Timestamped(0.2) },
                    new MaterialEsgIssue() { ExternalId = 3, SortKey = Timestamped(2), Type = Timestamped(MaterialIssueType.MaterialIssue), FinalWeight = Timestamped(0.3) },
                    new MaterialEsgIssue() { ExternalId = 4, SortKey = Timestamped(3), Type = Timestamped(MaterialIssueType.BaselineIssue), FinalWeight = Timestamped(0.4) },
                    new MaterialEsgIssue() { ExternalId = 5, SortKey = Timestamped(4), Type = Timestamped(MaterialIssueType.MaterialIssue), FinalWeight = Timestamped(0.5) },
                    new MaterialEsgIssue() { ExternalId = 6, SortKey = Timestamped(5), Type = Timestamped(MaterialIssueType.IdiosyncraticIssue), FinalWeight = Timestamped(0.3) },
                };

            profiles.Add(new ComprehensiveRiskRatingResearchProfile()
            {
                MaterialEsgIssues = inputList
            });

            riskRatingsSync.OrderRiskRatingsResearchProfiles(profiles);

            var meis = profiles.First().MaterialEsgIssues;

            Assert.True(meis.Count() == inputList.Count);
            Assert.True(meis.First().Type.Value == MaterialIssueType.BaselineIssue);
            Assert.True(meis.First().SortKey.Value == 0);
            Assert.True(meis.Last().Type.Value != MaterialIssueType.BaselineIssue);
            Assert.True(meis.Last().SortKey.Value == 5);
            Assert.True(meis.Skip(1).Take(1).First().FinalWeight.Value > meis.Skip(2).Take(1).First().FinalWeight.Value);
            Assert.True(meis.Skip(1).Take(2).First().FinalWeight.Value > meis.Skip(3).Take(1).First().FinalWeight.Value);
            Assert.True(meis.Last().Type.Value != MaterialIssueType.IdiosyncraticIssue);
        }

        private static SharedEntities.RiskRatingsResearch.Timestamped<T> Timestamped<T>(T value)
            => new SharedEntities.RiskRatingsResearch.Timestamped<T>() { Value = value };
    }
}
